package com.biwin.module.dict.starter.service.impl;

import com.biwin.common.app.exception.BwNotFoundException;
import com.biwin.module.dict.api.dto.DictionaryDto;
import com.biwin.module.dict.api.enums.BwDictionaryExceptionEnum;
import com.biwin.module.dict.api.service.IDictionaryService;
import com.biwin.module.dict.api.vo.DictionaryVo;
import com.biwin.module.dict.domain.entity.Dictionary;
import com.biwin.module.dict.domain.mapper.DictionaryMapper;
import com.biwin.module.dict.starter.repository.IDictionaryRepository;
import com.biwin.module.orm.starter.service.AbstractCurdService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

/**
 * TODO
 *
 * @author biwin
 * @since 0.0.1
 */
@Service
public class DictionaryServiceImpl extends AbstractCurdService<Dictionary, DictionaryVo, Long> implements IDictionaryService<Dictionary, DictionaryVo, Long> {

    private final IDictionaryRepository dictionaryRepository;
    private final DictionaryMapper dictionaryMapper;

    public DictionaryServiceImpl(IDictionaryRepository dictionaryRepository, DictionaryMapper dictionaryMapper) {
        super(dictionaryRepository);
        this.dictionaryRepository = dictionaryRepository;
        this.dictionaryMapper = dictionaryMapper;
    }

    @Override
    public DictionaryVo findByCodeDesc(String codeDesc) {
        Assert.notNull(codeDesc, "codeDesc must be not null");
        Dictionary dictionary =
                dictionaryRepository.findByCodeDesc(codeDesc).orElseThrow(() -> new BwNotFoundException(BwDictionaryExceptionEnum.DICT_NOT_EXIST));
        return toVo(dictionary);
    }

    @Override
    protected DictionaryVo toVo(Dictionary entity) {
        return dictionaryMapper.toVo(entity);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public DictionaryVo add(DictionaryDto dictionaryDto) {
        Dictionary dictionary = dictionaryMapper.toEntity(dictionaryDto);
        dictionaryRepository.save(dictionary);
        return toVo(dictionary);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public DictionaryVo update(DictionaryDto dictionaryDto) {
        Dictionary dictionary = dictionaryMapper.mergeEntity(dictionaryDto, findByIdE(dictionaryDto.getId()));
        dictionaryRepository.save(dictionary);
        return toVo(dictionary);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean enable(Long id) {
        return enableDict(id, true);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean disable(Long id) {
        return enableDict(id, false);
    }

    private boolean enableDict(Long id, boolean enabled) {
        Dictionary dictionary = super.findByIdE(id);
        dictionary.setEnabled(enabled);
        dictionaryRepository.save(dictionary);
        return true;
    }
}
